package com.gitee.wsl.ext.array

import com.gitee.wsl.ext.bitcode.umod

fun BooleanArray.rotateLeft(offset: Int = +1) = rotateRight(-offset)

fun ByteArray.rotateLeft(offset: Int = +1) = rotateRight(-offset)

fun CharArray.rotateLeft(offset: Int = +1) = rotateRight(-offset)

fun ShortArray.rotateLeft(offset: Int = +1) = rotateRight(-offset)

fun IntArray.rotateLeft(offset: Int = +1) = rotateRight(-offset)

fun LongArray.rotateLeft(offset: Int = +1) = rotateRight(-offset)

fun FloatArray.rotateLeft(offset: Int = +1) = rotateRight(-offset)

fun DoubleArray.rotateLeft(offset: Int = +1) = rotateRight(-offset)

fun <T> Array<T>.rotateLeft(offset: Int = +1) = rotateRight(-offset)

fun BooleanArray.rotateRight(offset: Int = +1) =
    _rotateRight(size, offset) { start, end -> reverse(start, end) }
fun ByteArray.rotateRight(offset: Int = +1) =
    _rotateRight(size, offset) { start, end -> reverse(start, end) }
fun CharArray.rotateRight(offset: Int = +1) =
    _rotateRight(size, offset) { start, end -> reverse(start, end) }
fun ShortArray.rotateRight(offset: Int = +1) =
    _rotateRight(size, offset) { start, end -> reverse(start, end) }
fun IntArray.rotateRight(offset: Int = +1) =
    _rotateRight(size, offset) { start, end -> reverse(start, end) }
fun LongArray.rotateRight(offset: Int = +1) =
    _rotateRight(size, offset) { start, end -> reverse(start, end) }
fun FloatArray.rotateRight(offset: Int = +1) =
    _rotateRight(size, offset) { start, end -> reverse(start, end) }
fun DoubleArray.rotateRight(offset: Int = +1) =
    _rotateRight(size, offset) { start, end -> reverse(start, end) }
fun <T> Array<T>.rotateRight(offset: Int = +1) =
    _rotateRight(size, offset) { start, end -> reverse(start, end) }

fun BooleanArray.rotatedLeft(offset: Int = +1): BooleanArray = copyOf().also { it.rotateLeft(offset) }
fun ByteArray.rotatedLeft(offset: Int = +1): ByteArray = copyOf().also { it.rotateLeft(offset) }
fun CharArray.rotatedLeft(offset: Int = +1): CharArray = copyOf().also { it.rotateLeft(offset) }
fun ShortArray.rotatedLeft(offset: Int = +1): ShortArray = copyOf().also { it.rotateLeft(offset) }
fun IntArray.rotatedLeft(offset: Int = +1): IntArray = copyOf().also { it.rotateLeft(offset) }
fun LongArray.rotatedLeft(offset: Int = +1): LongArray = copyOf().also { it.rotateLeft(offset) }
fun FloatArray.rotatedLeft(offset: Int = +1): FloatArray = copyOf().also { it.rotateLeft(offset) }
fun DoubleArray.rotatedLeft(offset: Int = +1): DoubleArray = copyOf().also { it.rotateLeft(offset) }
fun <T> Array<T>.rotatedLeft(offset: Int = +1): Array<T> = copyOf().also { it.rotateLeft(offset) }
fun BooleanArray.rotatedRight(offset: Int = +1): BooleanArray = copyOf().also { it.rotateRight(offset) }
fun ByteArray.rotatedRight(offset: Int = +1): ByteArray = copyOf().also { it.rotateRight(offset) }
fun CharArray.rotatedRight(offset: Int = +1): CharArray = copyOf().also { it.rotateRight(offset) }
fun ShortArray.rotatedRight(offset: Int = +1): ShortArray = copyOf().also { it.rotateRight(offset) }
fun IntArray.rotatedRight(offset: Int = +1): IntArray = copyOf().also { it.rotateRight(offset) }
fun LongArray.rotatedRight(offset: Int = +1): LongArray = copyOf().also { it.rotateRight(offset) }
fun FloatArray.rotatedRight(offset: Int = +1): FloatArray = copyOf().also { it.rotateRight(offset) }
fun DoubleArray.rotatedRight(offset: Int = +1): DoubleArray = copyOf().also { it.rotateRight(offset) }
fun <T> Array<T>.rotatedRight(offset: Int = +1): Array<T> = copyOf().also { it.rotateRight(offset) }

inline fun _rotateRight(size: Int, offset: Int, reverse: (start: Int, end: Int) -> Unit) {
    val offset = offset umod size
    if (offset == 0) return
    check(offset in 1 until size)
    reverse(0, size)
    reverse(0, offset)
    reverse(offset, size)
}

//fun ByteArray.rotate(offset: Int): ByteArray {
//    val effectiveOffset = offset % size
//    return if (effectiveOffset == 0 || isEmpty()) {
//        copyOf()
//    } else {
//        ByteArray(size) { i ->
//            this[(i - effectiveOffset + size) % size]
//        }
//    }
//}